package com.zhang.hadoop.netty.nio.buffer;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Arrays;

/**
 * @author zhang yufei
 * @date 2022/1/10 9:51 上午
 * @description: Scattering 将数据写入到 buffer 时,可以用 buffer 数组,依次写入[分数]
 * Gathering 从 buffer 读取数据时,可以采用 buffer 数组,依次读取
 **/
public class ScatteringAndGatheringTest {

    public static void main(String[] args) {
        try {
            //使用 ServerSocketChannel 和 SocketChannel
            ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
            InetSocketAddress inetSocketAddress = new InetSocketAddress(8000);
            //绑定端口到 socket,并启动
            serverSocketChannel.bind(inetSocketAddress);
            //创建 buffer 数组
            ByteBuffer[] byteBuffers = new ByteBuffer[2];
            byteBuffers[0] = ByteBuffer.allocate(5);
            byteBuffers[1] = ByteBuffer.allocate(3);
            //等待客户端连接(telnet)
            SocketChannel socketChannel = serverSocketChannel.accept();
            int messageLength = 8;
            //循环读取
            while (true) {
                int byteRead = 0;
                while (byteRead < messageLength) {
                    long l = socketChannel.read(byteBuffers);
                    byteRead += l;
                    System.out.println("byteRead=" + byteRead);
                    //使用流打印,看看当前的这个 buffer 的 position 和 limit
                    Arrays.asList(byteBuffers).stream()
                            .map(buffer -> "position=" + buffer.position() + ",limit=" + buffer.limit())
                            .forEach(System.out::println);
                }
                //将所有的 buffer 进行 flip
                Arrays.asList(byteBuffers).forEach(buffer -> buffer.flip());
                //将数据读出显示到客户端
                long byteWrite = 0;
                while (byteWrite < messageLength) {
                    long l = socketChannel.write(byteBuffers);
                    byteWrite += l;
                }
                Arrays.asList(byteBuffers).forEach(buffer -> {
                    buffer.clear();
                });
                System.out.println("byteRead=" + byteRead + "\tbyteWrite=" + byteWrite + "\tmessageLength=" + messageLength);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
